<template>
  <el-card shadow="never">
    <!-- 头部 -->
    <div slot="header">
      <el-breadcrumb separator='>'>
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>商品管理</el-breadcrumb-item>
        <el-breadcrumb-item>商品添加</el-breadcrumb-item>
      </el-breadcrumb>
    </div>
    <!-- 提醒 -->
    <el-alert title="增加商品"
              type="info"
              center
              effect="light"
              show-icon
              closable>
    </el-alert>
    <br>
    <!-- 步骤条  设置active属性，接受一个Number，表明步骤的 index，从 0 开始。-->
    <!-- active 要求是数字类型 -->
    <!-- activeIndex -->
    <el-steps :active="activeIndex-0"
              align-center>
      <el-step title="基本信息"
               description="基本信息"></el-step>
      <el-step title="商品参数"
               description="商品参数"></el-step>
      <el-step title="商品属性"
               description="商品属性"></el-step>
      <el-step title="商品图片"
               description="商品图片"></el-step>
      <el-step title="商品内容"
               description="商品内容"></el-step>
      <el-step title="完成"
               description="完成"></el-step>
    </el-steps>

    <!-- 大表单 -->
    <el-form :model="addFormInfo"
             ref="addFormInfo"
             :rules="addFormRules"
             label-width="80px"
             :inline="false"
             size="normal">
      <!-- 标签页，竖向 -->
      <!-- v-model 双向绑定值，绑定选项卡的 name，与哪一个tap的name对应，当前就会在哪个tab选项 要求是 string类型 比如 name="1"-->
      <!-- @tab-click tab 切换后触发事件 -->
      <!-- :before-leave="" tab 切换前触发，比如用于判断必选项，未选即阻止切换 tab 到其他栏 -->
      <el-tabs tab-position="left"
               :before-leave="beforeTabChange"
               @tab-click="tapClick"
               v-model="activeIndex">
        <!-- 竖行tap栏一  基本信息-->
        <el-tab-pane name="0"
                     label="基本信息">
          <el-row>
            <el-col :span="16">
              <el-form-item label="商品名称"
                            prop="goods_name">
                <el-input v-model="addFormInfo.goods_name"
                          placeholder="请输入商品名称"
                          clearable></el-input>
              </el-form-item>

              <el-form-item label="商品价格"
                            prop="goods_price">
                <el-input v-model="addFormInfo.goods_price"
                          placeholder="请输入商品价格"
                          clearable></el-input>
              </el-form-item>

              <el-form-item label="商品数量"
                            prop="goods_number">
                <el-input v-model="addFormInfo.goods_number"
                          placeholder="请输入商品数量"
                          clearable></el-input>
              </el-form-item>

              <el-form-item label="商品重量"
                            prop="goods_weight">
                <el-input v-model="addFormInfo.goods_weight"
                          placeholder="请输入商品重量"
                          clearable></el-input>
              </el-form-item>

              <el-form-item label="商品分类"
                            prop="goods_cat">
                <!-- 级联控件，选择商品分类 -->
                <el-cascader v-model="addFormInfo.goods_cat"
                             :options="allCateList"
                             clearable
                             :props="{
                           label:'cat_name',
                           value:'cat_id',
                           children:'children',
                       }"></el-cascader>
              </el-form-item>
            </el-col>
          </el-row>
        </el-tab-pane>
        <!-- 竖行tap栏二  商品参数-->
        <el-tab-pane name="1"
                     label="商品参数">
          <el-form-item v-for="(item,index) in manyList"
                        :key="index"
                        :label="item.attr_name"
                        size="normal">
            <el-checkbox-group v-model="item.check_attr_vals">
              <el-checkbox v-for="(val,idx) in item.attr_vals"
                           :key="idx"
                           :label="val"></el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-tab-pane>

        <!-- 竖行tap栏三  商品属性-->
        <el-tab-pane name="2"
                     label="商品属性">
          <el-form-item class="wz"
                        v-for="(item,index) in onlyList"
                        :key="index"
                        :label="item.attr_name"
                        size="normal">
            <el-input class="srk"
                      v-model="item.attr_vals"
                      size="normal">
            </el-input>
          </el-form-item>
        </el-tab-pane>

        <!-- 竖行tap栏四  商品图片-->
        <el-tab-pane name="3"
                     label="商品图片">
          <!-- 上传组件 会自己发起请求，不需要 axios-->
          <!-- list-type 上传图片的类型 picture 代表缩略图上传 -->
          <!-- action 上传的接口地址 -->
          <!-- :headers="{Authorization:token}" 因为组件要自己发送请求，所以需要我们在他的请求头里面添加自己的 token 字段-->
          <!-- :on-preview 属性，值是函数，预览时触发 -->
          <!-- :on-remove 属性，值是函数，删除时触发 -->
          <!-- :on-success 上传成功时触发 -->
          <!-- :file-list 上传的文件列表，每上传一个文件，都会保存到一个指定列表里 回显数据的时候用的上-->
          <el-upload class="upload-demo"
                     action="http://localhost:8888/api/private/v1/upload"
                     :headers="{Authorization:token}"
                     list-type="picture"
                     name="file"
                     :on-success="uploadSussess">
            <el-button size="small"
                       type="primary">点击上传</el-button>
          </el-upload>
        </el-tab-pane>

        <!-- 竖行tap栏五  商品内容-->
        <!-- options 指定编辑器的配置选项 -->
        <el-tab-pane name="4"
                     label="商品内容">
          <quill-editor v-model="addFormInfo.goods_introduce"
                        ref="myQuillEditor"
                        :options="editorOption">
          </quill-editor>
          <br>
          <el-button type="primary"
                     size="default"
                     @click="addSubmit">添加商品</el-button>

        </el-tab-pane>
      </el-tabs>
    </el-form>

  </el-card>
</template>

<script>
// 引入富文本编辑器插件
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'
// 引入 lodash 包，取名为 _  下划线
import _ from 'lodash'
export default {
  // 注册富文本编辑器插件
  components: {
    quillEditor
  },
  data() {
    // 拿到登录时获取的用户信息里面有 token
    const user = localStorage.getItem('HEIMA_SHOP_USER')
    const { token } = JSON.parse(user) //拿出 token
    return {
      token, //把token放在data中，上传图片时要用
      // 既是步骤条的 active 属性值，设置当前激活的步骤， 从 0 开始 (注意需隐式转换为数字类型)
      activeIndex: '0', //也是绑定当前选项卡的name,，activeIndex值与哪一个tap的name对应，当前就会在哪个tab选项(选项卡要求name是字符串类型)
      addFormInfo: {
        goods_name: '', //商品名称
        goods_cat: [], //商品分类
        goods_price: '', //商品价格
        goods_number: '', //商品数量
        goods_weight: '', //商品重量
        goods_introduce: '', //商品介绍
        pics: [], //商品图片路径
        attrs: [] //商品参数/动态参数和静态属性
      },
      //   表单验证规则
      addFormRules: {
        goods_name: [
          { required: true, message: '商品名称必填', trigger: 'blur' }
        ],
        goods_cat: [
          { required: true, message: '商品分类必填', trigger: 'blur' }
        ],
        goods_price: [
          { required: true, message: '商品价格必填', trigger: 'blur' }
        ],
        goods_number: [
          { required: true, message: '商品数量必填', trigger: 'blur' }
        ],
        goods_weight: [
          { required: true, message: '商品重量必填', trigger: 'blur' }
        ]
      },
      allCateList: [], //所有分类
      manyList: [], //用来存储动态属性
      onlyList: [], //用来存储静态参数
      editorOption: {
        //编辑器的配置选项
        // placeholder，文本域默认提示文字
        placeholder: '请输入商品内容'
      }
    }
  },
  created() {
    this.getAllCateList()
  },
  //   计算属性
  computed: {
    cateId() {
      // 实时计算分类名称被选中的长度(已经设置了必须选中到第三层，否则清空选项数组)
      // 如果选到了第三层，说明选了分类名称
      if (this.addFormInfo.goods_cat.length === 3) {
        // 就把当前选中的所有分类名称数组 addFormInfo.goods_cat 返回出去
        // 又因为只需要最后一位的数据,并且数组只能是3位,多了没有,少了选不中,所以返回的是索引 2
        return this.addFormInfo.goods_cat[2]
      } else {
        //   如果没选,返回空字符串
        return ''
      }
    }
  },
  methods: {
    // 请求分类选项列表
    async getAllCateList() {
      const { data: res } = await this.$axios.get('/categories')
      //   失败
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      //   成功
      this.allCateList = res.data
    },
    // tab切换前
    beforeTabChange(activeName, oldActiveName) {
      //   console.log(activeName) //即将进入的标签页name名称 到哪里去
      //   console.log('==>' + oldActiveName) //即将离开的标签页name名称 从哪里来
      //   console.log(this.addFormInfo.goods_cat)
      if (oldActiveName === '0') {
        //如果是要从0号tab离开
        //就要进入判断，判断ddFormInfo.goods_cat.length是否等于3，也就是是否选了分类参数
        if (this.addFormInfo.goods_cat.length !== 3) {
          // 没选就提醒
          this.$message.warning('请选择商品分类！！！')
          //并且返回 false 阻止跳转
          return false
        }
      }
    },
    // tab切换后
    tapClick() {
      // activeIndex的值是字符串，通过v-model 与tab 的name 双向绑定
      if (this.activeIndex === '1' && !this.manyList.length) {
        //并且，如果manyList已经有了，就不要再发送请求，不要渲染,以防止每一次切换tap后，原来选的都没了
        // activeIndex等于2说明切换到了tap栏2 商品参数(静态参数)
        this.getParamsList('many') //tab栏2的内容是商品的静态参数，所以调用getParamsList函数传入实参 字符串 many，以便通过getParamsList函数获取 many 数据(静态参数)
      } else if (this.activeIndex === '2' && !this.onlyList.length) {
        //activeIndex等于3说明切换到了tap栏3 商品属性(动态属性)
        this.getParamsList('only') //tab栏2的内容是商品的动态属性，所以调用getParamsList函数传入实参 字符串 only，以便通过getParamsList函数获取 many 数据(动态属性)
      }
    },
    // 获取动态或静态数据
    async getParamsList(sel) {
      // 发送请求
      const { data: res } = await this.$axios.get(
        `/categories/${this.cateId}/attributes`,
        {
          // 请求参数是 many 还是  only，取决于传入的参数 sel
          params: { sel }
        }
      )
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      //   console.log(res.data)
      // 如果是 many 类型的数据，要单独处理一下
      if (sel === 'many') {
        // 因为man数据是字符串，所以在 el-checkbox 组件进行遍历的时候，会把每一个字符当成一个 value 值，
        // 从而出现一大堆多选框，所以再获取到 mayn 数据的时候，要把他转成逗号分隔的数组，但是又不能影响到原来的数据
        // 所以这里使用map方法
        // map() 方法返回一个新数组，数组中的元素为原始数组元素调用函数处理后的值。
        // map() 方法按照原始数组元素顺序依次处理元素。
        // 注意： map() 不会对空数组进行检测。
        // 注意： map() 不会改变原始数组。
        // 这个方法的回调函数有三个参数
        // 形参1是必须的，代表当前要处理的那个元素的值,就是res.data里面的
        // 形参2可选，代表当前元素的索引值,
        // 形参3可选，代表当前元素属于的数组对象
        res.data = res.data.map(val => {
          //res.data 就是请求过来的，上个tap栏选中的参数名  例如 大家电/电视/曲面电视这个分类下面的 例如 版式，品牌
          //   console.log(val) //与res.data一样,不会影响原来的数据
          // 判断 attr_vals  是否存在 attr_vals 就是分类动态静态参数，例如 24k人工智能(小标签)，TCL电视 55A950C(商品属性) 啥啥啥的
          // 是个字符串，如果有就分割为数组，没有就返回空数组
          val.attr_vals = val.attr_vals ? val.attr_vals.split(',') : []
          //checkout 复选框的 v-model 的值就是被选中的选项，这里绑定一个数组 tem.check_attr_vals，
          val.check_attr_vals = [] //用于存放选中的参数内容 初始为空，默认都不选中，后面每选中一个都会被加入数组，同时取消一个，也会从数组里面消失
          return val
        })
      }
      //   请求过来的参数放入哪一个容器，取决于 形参 sel
      this[sel + 'List'] = res.data
      //   console.log(res.data)
    },
    uploadSussess(response, file, fileList) {
      // 上传组件会自己发送请求，不需要 axios
      console.log(response) //上传的图片路径以及请求信息 只有data和meta
      //   console.log(file) //上传的图片路径以及请求信息 更详细，处理地址，还有图片名称，id
      //   console.log(fileList) //同2，不过2是对象，这个是数组
      if (response.meta.status !== 200)
        // 失败
        return this.$message.error(response.meta.mag)
      // 成功
      this.$message.success('上传成功')
      //   把上传的文件路径 push 到 this.addFormInfo.pics 数组进行保存
      this.addFormInfo.pics.push({
        pic: response.data.tmp_path
      })
    },
    // 添加提交
    addSubmit() {
      this.$refs.addFormInfo.validate(async valid => {
        // console.log(valid) 布尔值，只要有一个不符合校验规则的，就为 false
        if (!valid) {
          return this.$message.error('必填项不能为空')
        }
        // 对表单数据进行一次深拷贝，这样操作才不会影响原来的数组，利用 lodash 插件使用深拷贝方法  _.cloneDeep (注意，_ 是lodash的名字)，
        const formData = _.cloneDeep(this.addFormInfo)
        // 商品参数处理
        let attrs = []
        // forEach 遍历 动态参数 manyList 数组，拿出需要的数据， push 到 attr 空数组
        this.manyList.forEach(val => {
          attrs.push({
            attr_id: val.attr_id,
            // 转为字符串
            attr_value: val.check_attr_vals.join(',')
          })
        })

        // 商品属性处理
        // forEach 遍历 静态属性 onlyList 数组，拿出需要的数据， push 到 attr 空数组
        this.onlyList.forEach(val => {
          attrs.push({
            attr_id: val.attr_id,
            // 原本就是字符串，不需要转
            attr_value: val.attr_vals
          })
        }),
          (formData.attrs = attrs)
        // 把拷贝后的数据转为字符串
        formData.goods_cat = formData.goods_cat.join(',')
        // 发送请求
        const { data: res } = await this.$axios.post('/goods', formData)
        // 失败提醒
        if (res.meta.status !== 201) return this.$message.error(res.meta.msg)
        // 成功提醒
        this.$message.success(res.meta.msg)
        // 跳转到列表
        this.$router.push('/goods')
        // console.log(formData)
      })
    }
  }
}
</script>
<style scope>
/* 富文本编辑器输入域的高度 */
.ql-container {
  height: 300px;
}

/* 商品属性 */
/* 输入框前面的文字 */
.wz {
  word-break: keep-all !important;
  white-space: nowrap !important;
  margin-top: 15px !important;
}

/* 输入框 */
.srk {
  width: 900px !important;
  margin-left: 60px !important;
}
</style>